﻿#ifndef WRWORKTCPCOMMSERVEREVENTSOURCE
#define WRWORKTCPCOMMSERVEREVENTSOURCE

#include "WRWorkTcpCommServerInterface.h"
#include "WRWorkTcpCommServerInterfaceActivator.h"
#include "../WRWorkTcpComm.h"
#include "../WRWorkTcpCommConsts.h"
#include "../../WRSoft-Utility/Framing/WREventSource.h"
#include "../../WRSoft-Utility/Runtime/WRDataPacket.h"

/********************
class Writer
{
public:
    int count(const T& val);
    int write(const T& val, unsigned char* buf);
};
********************/

//表示工作TCP通讯服务器事件源接口。
template <class T, class TWriter>
class WRWorkTcpCommServerEventSource : public WRWorkTcpCommServerInterface, public WREventHandler
{
private:
    WREventSource* m_source;
    TWriter m_writer;
    bool m_status;

public:
    //初始化工作TCP通讯服务器事件源接口。
    WRWorkTcpCommServerEventSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommServerObject* target, WREventSource* source)
        : WRWorkTcpCommServerInterface(uuid, name, index, target), m_source(source), m_status(true)
    {
        //add code here
    }
    //初始化工作TCP通讯服务器事件源接口。
    WRWorkTcpCommServerEventSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommServerAffair* target, WREventSource* source)
        : WRWorkTcpCommServerInterface(uuid, name, index, target), m_source(source), m_status(true)
    {
        //add code here
    }

    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommServerEventSource(void)
    {
        m_status = false;
        m_source->removeHandler(this);
    }

    //当事件改变后调用此方法。
    void doProcess(const void* value)
    {
        if (m_status)
        {
            int dataLen = m_writer.count(*(const T*)value);
            int fillLen = 0;//填充长度
            {
                int remain = dataLen % 8;
                if (remain > 0) fillLen = 8 - remain;
            }

            WRDataPacket* packet;
            if (affair())
            {
                char* p;
                int cmdLen = 40 + dataLen + fillLen;
                packet = WRDataPacket::create(cmdLen);
                packet->buffer(&p);

                WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                p += 4;
                WRBytes::write((WR32s)(cmdLen), p);//帧长度
                p += 4;
                WRBytes::write((WR16u)(object()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p);//类型（工作事务）
                p += 2;
                WRBytes::write((WR32s)(affair()->id()), p);
                p += 4;
                WRBytes::write((WR16u)(affair()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p);//类型（接口处理）
                p += 2;
                WRBytes::write((WR16u)(index()), p);//接口索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::EventProcess, p);//事件处理
                p += 6;
                WRBytes::write((WR32s)(dataLen), p);//数据长度
                p += 4;
                m_writer.write(*(const T*)value, (unsigned char*)p);//参数数据
                p += dataLen;
                p += fillLen; ;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p);//版本
                p += 4;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p);//帧尾
            }
            else
            {
                char* p;
                int cmdLen = 32 + dataLen + fillLen;
                packet = WRDataPacket::create(cmdLen);
                packet->buffer(&p);

                WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                p += 4;
                WRBytes::write((WR32s)(cmdLen), p);//帧长度
                p += 4;
                WRBytes::write((WR16u)(object()->index()), p);//工作对象索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p);//类型（接口处理）
                p += 2;
                WRBytes::write((WR16u)(index()), p);//接口索引
                p += 2;
                WRBytes::write((WR16u)WRWorkTcpComm::EventProcess, p);//事件处理
                p += 6;
                WRBytes::write((WR32s)(dataLen), p);//数据长度
                p += 4;
                m_writer.write(*(const T*)value, (unsigned char*)p);//参数数据
                p += dataLen;
                p += fillLen; ;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p);//版本
                p += 4;
                WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p);//帧尾
            }

            if (!object()->sendData(packet))
            {
                packet->release();
                m_status = false;
            }
        }
    }

    //执行关闭处理。
    void shutdown(void)
    {
        m_status = false;
        m_source->removeHandler(this);
    }

    //处理数据。
    void procData(const unsigned char* buf, int)
    {
        WR16u cmdType = WRBytes::read<WR16u>(buf);;
        switch(cmdType)
        {
        case WRWorkTcpComm::EventStarted:
            m_source->addHandler(this);
            break;
        case WRWorkTcpComm::EventStopped:
            m_source->removeHandler(this);
            break;
        default:
            break;
        }
    }
};

//表示工作TCP通讯服务器事件激活器。
template <class T, class TWriter, class TUuidValue, class TNameValue>
class WRWorkTcpCommServerEventSourceActivator : public WRWorkTcpCommServerInterfaceActivator
{
public:
    //初始化工作TCP通讯服务器事件激活器。
    WRWorkTcpCommServerEventSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::enrollServerInterface(uuid(), this);
    }
    //释放当前对象所占用的相关资源。
    ~WRWorkTcpCommServerEventSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::cancelServerInterface(uuid());
    }

    //创建接口实例。
    WRWorkTcpCommServerInterface* create(int index, WRWorkTcpCommServerObject* target, void* reference)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommServerEventSource<T, TWriter>(uuid(), name(), index, target, (WREventSource*)reference);
    }
    //创建接口实例。
    WRWorkTcpCommServerInterface* create(int index, WRWorkTcpCommServerAffair* target, void* reference)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommServerEventSource<T, TWriter>(uuid(), name(), index, target, (WREventSource*)reference);
    }
};

#endif // WRWORKTCPCOMMSERVEREVENTSOURCE
